import React, { useEffect, useMemo, useState } from "react";
import styles from "@styles/search.module.less";
import Back from "@shared/back";
import GeekIcon from "@shared/geekIcon";
import Suggestion from "@pages/search/widgets/suggestion";
import { useDebounce } from "use-debounce";
import {
  searchEndpoints,
  useLazyRequestSuggestionQuery,
} from "@service/searchEndpoints";
import { useTypedDispatch } from "@store/index";
import History from "@pages/search/widgets/history";
import { addHistory } from "@slice/history";
import { useNavigate } from "react-router-dom";

export default function Search() {
  // 用于记录用户在搜索框中输入的内容
  const [q, setQ] = useState("");
  // 得到一个防抖之后的值
  const [debounceValue] = useDebounce(q, 1000);
  // 得到用于获取联想关键词的方法
  const [requestSuggestion, { data: suggestion }] =
    useLazyRequestSuggestionQuery();
  const dispatch = useTypedDispatch();
  const navigate = useNavigate();
  // 监听用于输入
  useEffect(() => {
    // 由于组件初次挂载时, useEffect 会执行一次, 此时用户还没有输入任何搜索关键词, 所以不需要发请求
    if (debounceValue.trim().length > 0) {
      // 发送请求获取搜索联想关键词
      requestSuggestion(debounceValue);
    } else {
      // 清空本地已缓存的数据
      dispatch(searchEndpoints.util.resetApiState());
    }
  }, [debounceValue, dispatch, requestSuggestion]);

  // 用于在搜索联想建议列表项中匹配用户输入的内容
  const reg = useMemo(() => new RegExp(debounceValue, "gi"), [debounceValue]);

  // 用于判断联想关键词列表是否存在
  const hasSuggestion = useMemo(() => {
    // 如果联想关键词列表为 undefined, 表示没有结果
    if (typeof suggestion === "undefined") return false;
    // 如果联想关键词列表长度不等于0 返回 true, 否则返回 false
    return suggestion.data.options.filter((item) => item !== null).length !== 0;
  }, [suggestion]);

  return (
    <div className={styles.search_page}>
      <div className={styles.header}>
        <Back />
        <div className={styles.input}>
          <GeekIcon type={"iconbtn_search"} />
          <input
            type="search"
            placeholder={"请输入关键字搜索"}
            value={q}
            onChange={(event) => setQ(event.target.value)}
          />
        </div>
        <span
          onClick={() => {
            // 保存搜索历史关键字
            dispatch(addHistory({ name: q }));
            // 跳转到搜索结果页面
            navigate(`/search/${q}`);
          }}
          className={styles.search_btn}
        >
          搜索
        </span>
      </div>
      {hasSuggestion && (
        <Suggestion
          suggestions={suggestion!.data.options
            .filter((item) => item !== null)
            .map((item) => ({
              origin: item,
              name: item.replace(reg, (str) => `<span>${str}</span>`),
            }))}
        />
      )}
      {!hasSuggestion && <History />}
    </div>
  );
}
